home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / asmsrc / thesource-7.lha / Source / DefFunc.lha / DefFunc / dfcparse.y < prev    next >
Text File  |  1993-12-14  |  9KB  |  329 lines

  1. /****************************************************************
  2.  *
  3.  *    Copyright (c) 1993  Ke Jin
  4.  *
  5.  *    Permission to use, copy, modify, and distribute
  6.  *    this software and its documentation without fee
  7.  *    is granted, provided that the author's name and
  8.  *    this copyright notice are retained.
  9.  *
  10.  * ------------------------------------------------------------
  11.  *
  12.  *   dfcparse.y -- the yacc file of defunc parser 
  13.  *
  14.  *   public  function : yyparse();
  15.  *                      yyinit();
  16.  *                      getparsetree();
  17.  *
  18.  *   public  variable : exparserror;
  19.  *  
  20.  *   private function : addnode();
  21.  *                      yyreverse();
  22.  *                      yyerror();
  23.  *                      yywrap();
  24.  *
  25.  *   private variable : yyparsetree;
  26.  *                      yytreesize;
  27.  *                      newnode;
  28.  *
  29.  ****************************************************************/
  30.  
  31. %{
  32. #include <stdio.h>
  33. #include <malloc.h>
  34. #include <math.h>
  35. #include <string.h>
  36. #include "dfctree.h"
  37. #include "dfcsymtable.h"
  38.  
  39. char*         exparserror;
  40. static char   ermsgbuff[128];
  41. static Node*  yyparsetree; 
  42. static int    yytreesize;
  43. static Node   newnode;
  44.  
  45. #if NeedFunctionPrototypes
  46.   int yyparse(void);
  47.   static int yyreverse(void);
  48. #else
  49.   extern int yyparse();
  50.   extern int yyreverse();
  51. #endif
  52.  
  53. #if NeedFunctionPrototypes
  54.   static int addnode(Node *ptr)
  55. #else
  56.   static int addnode(ptr)
  57.   Node *ptr;
  58. #endif
  59. {
  60.     yytreesize++;
  61.  
  62.     if(yytreesize==1)
  63.     {
  64.         yyparsetree = (Node*)malloc(sizeof(Node));
  65.     }
  66.     else
  67.     {
  68.         yyparsetree = (Node*)realloc((Node*)yyparsetree, 
  69.                                  yytreesize*sizeof(Node));
  70.     }
  71.     if(yyparsetree==0)
  72.     {
  73.     perror("malloc/realloc in addnode()");
  74.     exit(1);
  75.     }
  76.  
  77.     if(yyparsetree == 0) 
  78.     {
  79.         fprintf(stderr, "fail to allocate memory in add node\n");
  80.         exit(1);
  81.     }
  82.  
  83.     /* yyparsetree[yytreesize-1] = *ptr; */
  84.     memcpy(yyparsetree+yytreesize-1, ptr, sizeof(Node)); 
  85.  
  86.     return yytreesize-1;
  87. };
  88.  
  89. %}
  90.  
  91. %union {
  92.     int    nodeidx;
  93.     int    argidx;
  94.     double value;
  95.     double (*fnctptr)();
  96.     char   name[32];
  97. }
  98.  
  99. %token <value>   CONST  /* constant              */
  100. %token <argidx>  ARG    /* function arguments    */
  101. %token <fnctptr> FNCT   /* intrinsic function    */
  102. %token <name>    SYM    /* new symbol            */
  103. %type  <nodeidx> expr   /* function expression   */
  104.  
  105. %left  '-' '+'
  106. %left  '*' '/'
  107. %left  SIG
  108. %right '^'
  109.  
  110. %% /*  ------------------- syntax rules ------------------------ */ 
  111. input : '\n'               {  
  112.                   return 0;
  113.                 } 
  114.       | ';'                {
  115.                   return 0;
  116.                            }
  117.       | expr '\n'          {  
  118.                               return yyreverse(); 
  119.                            } 
  120.       | expr ';'           {
  121.                   return yyreverse();
  122.                            }
  123.       | error '\n'         {  
  124.                               return -1;
  125.                            } 
  126.       ;
  127.  
  128. expr  : CONST              {  
  129.                               newnode.type = const_node;
  130.                               newnode.content.value = $1;
  131.  
  132.                               $$ = addnode(&newnode); 
  133.                            }
  134.       | SYM                {
  135.                   sprintf(ermsgbuff, 
  136.                   "unknow token \"%s\"", $1);
  137.                   exparserror = ermsgbuff;
  138.                   return -1;
  139.                            }
  140.       | CONST '(' ')'      {
  141.                   newnode.type = const_node;
  142.                   newnode.content.value = $1;
  143.  
  144.                   $$ = addnode(&newnode);
  145.                            }
  146.       | CONST '(' expr ')' {
  147.                   newnode.type = const_node;
  148.                   newnode.content.value = $1;
  149.  
  150.                   $$ = addnode(&newnode);
  151.                }
  152.       | ARG                {
  153.                               newnode.type = arg_node;
  154.                   newnode.content.argidx = $1;
  155.                               $$ = addnode(&newnode);
  156.                            }
  157.       | FNCT '(' expr ')'  { 
  158.                               newnode.type = simplex_fnct_node;
  159.                               newnode.content.fnctptr = $1;
  160.                               newnode.right = $3;
  161.  
  162.                               $$ = addnode(&newnode);
  163.                            }
  164.       | FNCT '(' expr ',' expr ')' {
  165.                               newnode.type = duplex_fnct_node;
  166.                               newnode.content.fnctptr = $1;
  167.                               newnode.left = $3;
  168.                               newnode.right= $5;
  169.  
  170.                               $$ = addnode(&newnode);
  171.                            }
  172.       | FNCT '(' expr ',' expr ',' expr ')' {
  173.                   exparserror 
  174.                 = "not support triplex function yet";
  175.                       return -1;    
  176.                        } 
  177.       | expr '+' expr      {
  178.                               newnode.type = binary_op_node;
  179.                               newnode.content.op = op_sum;
  180.                               newnode.left = $1;
  181.                               newnode.right= $3;
  182.  
  183.                               $$ = addnode(&newnode);
  184.                            }
  185.       | expr '-' expr      {
  186.                               newnode.type = binary_op_node;
  187.                               newnode.content.op = op_sub;
  188.                               newnode.left = $1;
  189.                               newnode.right= $3;
  190.  
  191.                               $$ = addnode(&newnode);
  192.                            }
  193.       | expr '*' expr      {
  194.                               newnode.type = binary_op_node;
  195.                               newnode.content.op = op_mul;
  196.                               newnode.left = $1;
  197.                               newnode.right= $3;
  198.  
  199.                               $$ = addnode(&newnode);
  200.                            }
  201.       | expr '/' expr      {
  202.                               newnode.type = binary_op_node;
  203.                               newnode.content.op = op_div;
  204.                               newnode.left =$1;
  205.                               newnode.right=$3;
  206.  
  207.                               $$ = addnode(&newnode); 
  208.                            }
  209.       | '-' expr %prec SIG {
  210.                               newnode.type = unary_op_node; 
  211.                   newnode.content.op = op_neg;
  212.                               newnode.right = $2;
  213.  
  214.                               $$ = addnode(&newnode);
  215.                            }
  216.       | '+' expr %prec SIG { 
  217.                               $$ = $2;
  218.                            } 
  219.       | expr '^' expr      {
  220.                               newnode.type = duplex_fnct_node;
  221.                               newnode.content.fnctptr = pow;
  222.                               newnode.left = $1;
  223.                               newnode.right= $3;
  224.  
  225.                               $$ = addnode(&newnode);
  226.                            } 
  227.       | '(' expr ')'       { 
  228.                               $$ = $2; 
  229.                            }
  230.       ;
  231. %% /* --------------------------------------------------------- */
  232. #include "dfcscan.h"
  233.  
  234. #if NeedFunctionPrototype
  235.   int yyinit(char* expr)
  236. #else
  237.   int yyinit(expr)
  238.   char *expr; 
  239. #endif
  240. {
  241.     initargu();
  242.  
  243.     yyexpr = expr;
  244.     yyexprlen = strlen(yyexpr);
  245.     yypos = 0;
  246.     yytreesize = 0;
  247.  
  248.     return 0;
  249. };
  250.  
  251. #if NeedFunctionPrototypes
  252.   static int yyreverse(void)
  253. #else
  254.   static int yyreverse()  
  255. #endif
  256. /* yyparse() use a LALR(1) bottom-up algorithem to construct the
  257.    parse tree. Thus the result tree is upsetdown, i.e. the root
  258.    is place on the end of the yyparsetree[]. yyreverse make it
  259.    in right order, i.e. yyparsetree[0] be the root */
  260. {
  261.     int   i;
  262.     Node* buff;
  263.  
  264.     if(yytreesize==0) return 0;
  265.  
  266.     buff = (Node*)malloc(sizeof(Node)*yytreesize);
  267.     if(buff==0) 
  268.     {
  269.     perror("malloc in reverse()");
  270.     exit(1);
  271.     }
  272.  
  273.     for(i=0; i<yytreesize; i++) /* reverse */
  274.     {
  275.     
  276.      /* buff[i] = yyparsetree[yytreesize-1-i]; */
  277.     memcpy(buff+i, yyparsetree+yytreesize-1-i, sizeof(Node));
  278.     buff[i].left = yytreesize - 1 - buff[i].left;
  279.     buff[i].right= yytreesize - 1 - buff[i].right;
  280.  
  281.     }
  282.  
  283.     for(i=0; i<yytreesize; i++) /* put it back */ 
  284.     {
  285.     yyparsetree[i] = buff[i];
  286.     }
  287.  
  288.     free(buff);
  289.  
  290.     return yytreesize;
  291. };
  292.  
  293. #if NeedFunctionPrototypes
  294.   int getparsetree(Node* buff)
  295. #else
  296.   int getparsetree(buff)
  297.   Node* buff;
  298. #endif
  299. /* copy the parse into buff */
  300. {
  301.     int i;
  302.  
  303.     for(i=0; i<yytreesize; i++)
  304.     {
  305.     buff[i] = yyparsetree[i];
  306.     }
  307.  
  308.     return yytreesize;
  309. };
  310.  
  311. #if NeedFunctionPrototypes
  312.   static void yyerror(char* s)
  313. #else
  314.   static yyerror(s)
  315.   char *s;
  316. #endif
  317. {
  318.     exparserror=s;
  319. };
  320.  
  321. #if NeedFunctionPrototypes
  322.   static int yywrap(void)
  323. #else
  324.   static int yywrap()
  325. #endif
  326. {
  327.    return 1;
  328. };
  329.